#include <stdlib.h>
#include <GL/glut.h>
#include <GL/glext.h>
#include <FreeImage.h>
#include <assert.h>
#include "TextureObject.hpp"

using namespace std;

#ifndef TRUE
   #define TRUE    1
#endif //TRUE

#ifndef FALSE
   #define FALSE   0
#endif //FALSE


TextureObject::TextureObject( std::string fileName, TexType textureType )
{
	//! Set texture type (for now this is storage for info if texture have alpha enabled).
	m_textureType = textureType;

	//! Use FreeImage library to recognize image file type.
	FREE_IMAGE_FORMAT fileFormat = FreeImage_GetFileType(fileName.c_str());

	//! Use FreeImage library to load data from image file.
	FIBITMAP* bitmap = FreeImage_Load(fileFormat, fileName.c_str());

	BOOL transparent = FreeImage_IsTransparent(bitmap);

	//! Generate texture with loaded data.
	glGenTextures(1, &m_textureID);
	glBindTexture(GL_TEXTURE_2D, m_textureID);

	assert( (m_textureType == TEXTURE_ALPHA && transparent == TRUE) || 
		(m_textureType == TEXTURE_STANDARD && transparent == FALSE) );

	if(m_textureType == TEXTURE_ALPHA)
	{
		glTexImage2D( GL_TEXTURE_2D, 0, GL_RGBA, FreeImage_GetWidth( bitmap ), FreeImage_GetHeight( bitmap ), 0, GL_BGRA_EXT,
		          GL_UNSIGNED_BYTE, FreeImage_GetBits( bitmap ) );

		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST );
	}
	else
	{
		glTexImage2D( GL_TEXTURE_2D, 0, GL_RGB, FreeImage_GetWidth( bitmap ), FreeImage_GetHeight( bitmap ), 0, GL_BGR_EXT,
		          GL_UNSIGNED_BYTE, FreeImage_GetBits( bitmap ) );

		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR );
		glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR );
	}






	//! Delete unnecessary data.
	FreeImage_Unload( bitmap );
}
TextureObject::TextureObject(const FIBITMAP *pFIBMP)
{
	m_textureType = TEXTURE_STANDARD;

	//! Generate texture with passed data.
	glGenTextures(1, &m_textureID);
	glBindTexture(GL_TEXTURE_2D, m_textureID);

	glTexImage2D(GL_TEXTURE_2D, 0, 3, FreeImage_GetWidth(const_cast<FIBITMAP*>(pFIBMP)), FreeImage_GetHeight(const_cast<FIBITMAP*>(pFIBMP)), 0, GL_BGR_EXT,
		GL_UNSIGNED_BYTE, FreeImage_GetBits(const_cast<FIBITMAP*>(pFIBMP)));

	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
	glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
}

TextureObject::~TextureObject()
{
	//! Delete texture from video RAM.
	glDeleteTextures(1, &m_textureID);
}

const GLuint& TextureObject::getTextureID() const
{
	//! Return ID of texture.
	return m_textureID;
}

const TexType& TextureObject::getTextureType()
{
	return m_textureType;
}
